package com.suredy.app.porject.ctrl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.suredy.app.ctrl.AppBaseCtrl;
import com.suredy.app.porject.constants.BidStatus;
import com.suredy.app.porject.constants.ContractStatus;
import com.suredy.app.porject.constants.ContractType;
import com.suredy.app.porject.constants.FlowStatus;
import com.suredy.app.porject.ctrl.view.ViewRoleCtrl;
import com.suredy.app.porject.model.Bid;
import com.suredy.app.porject.model.BidMoney;
import com.suredy.app.porject.model.Contract;
import com.suredy.app.porject.model.ContractPayinPlan;
import com.suredy.app.porject.model.ContractPayoutPlan;
import com.suredy.app.porject.model.ContractWorkPlan;
import com.suredy.app.porject.service.BidMoneySrv;
import com.suredy.app.porject.service.BidSrv;
import com.suredy.app.porject.service.ContractMoneySrv;
import com.suredy.app.porject.service.ContractPayinPlanSrv;
import com.suredy.app.porject.service.ContractPayoutPlanSrv;
import com.suredy.app.porject.service.ContractSrv;
import com.suredy.app.porject.service.ContractWorkPlanSrv;
import com.suredy.app.porject.service.FlowOfBid2UserSrv;
import com.suredy.app.porject.service.FlowOfContract2UserSrv;
import com.suredy.app.porject.service.ProjectConstants;
import com.suredy.core.service.MySQlConvertOrder;
import com.suredy.core.service.OrderEntity;

/**
 * 首页，我的应用控制器
 * 
 * @author VIVID.G
 * @since 2015-10-12
 * @version v0.1
 */
@Controller
@RequestMapping("/front-page")
public class FrontPageCtrl extends AppBaseCtrl {

	/* 七天以内 */
	private final int ALARM_DATE_SIZE = 7;

	@Autowired
	private BidSrv bidSrv;

	@Autowired
	private ContractSrv contractSrv;

	@Autowired
	private FlowOfBid2UserSrv bid2UserSrv;

	@Autowired
	private FlowOfContract2UserSrv contract2UserSrv;

	@Autowired
	private ContractPayinPlanSrv contractPayinPlanSrv;

	@Autowired
	private ContractPayoutPlanSrv contractPayoutPlanSrv;

	@Autowired
	private ContractWorkPlanSrv contractWorkPlanSrv;

	@Autowired
	private BidMoneySrv bidMoneySrv;

	@Autowired
	private ContractMoneySrv contractMoneySrv;

	@Autowired
	private ProjectConstants constants;

	@RequestMapping(method = RequestMethod.GET)
	public String index(Model model) {
		String view = "app/front-page/index";

		ViewRoleCtrl vc = new ViewRoleCtrl(this.getUser(), this.getRoleCodesFromSession());

		model.addAttribute("roles", vc);

		// 招标专责
		if (vc.isCanCreateBid()) {
			model.addAttribute("toBid", this.myTodoBid(null));
			model.addAttribute("noServerMoneyBid", this.getBidWithNoServerMoneyInfo(null));
		}

		// 合同专责
		if (vc.isCanCreateContract() && vc.isContractMain())
			model.addAttribute("toContract", this.myBidForContract(null, null));

		// 项目专责
		if (vc.isCanWork())
			model.addAttribute("workPlan", this.myWorkPlan());

		// 收款专责
		if (vc.isCanInMoney())
			model.addAttribute("payinPlan", this.myPayinPlan());

		// 付款专责
		if (vc.isCanOutMoney())
			model.addAttribute("payoutPlan", this.myPayoutPlan());

		// 待履行合同
		if (vc.isCanReceiveContract())
			model.addAttribute("contractForStart", this.contractForStart());

		// 待回收投标保证金
		if (vc.isCanManageBid())
			model.addAttribute("backTbbzj", this.getBackTbbzj());

		// 合同质保金（保函）
		if (vc.isBzjManager() && vc.isCanManageContract() && vc.isContractMain())
			model.addAttribute("contractBzj", this.getContractBzj());

		return view;
	}

	@RequestMapping(value = "/bid-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getBidTotal(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		Map<String, Long> data = null;

		if (start == null || end == null)
			data = this.bidSrv.getBidStatusTotal(null, null);
		else
			data = this.bidSrv.getBidStatusTotal(start, end);

		Map<String, Object> ret = new HashMap<String, Object>();

		ret.put("xData", data.keySet());
		ret.put("yData", data.values());

		return ret;
	}

	@RequestMapping(value = "/contract-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getContractTotal(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		Map<String, Long> data;
		if (start == null || end == null)
			data = this.contractSrv.getContractTotal(null, null, ContractType.MAIN_CONTRACT_TYPES);
		else
			data = this.contractSrv.getContractTotal(start, end, ContractType.MAIN_CONTRACT_TYPES);

		Map<String, Object> ret = new HashMap<String, Object>();

		ret.put("xData", data.keySet());
		ret.put("yData", data.values());

		return ret;
	}

	@RequestMapping(value = "/contract-satus-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getContractStatusTotal(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		Map<String, Long> data;
		if (start == null || end == null)
			data = this.contractSrv.getContractStatusTotal(null, null, ContractType.MAIN_CONTRACT_TYPES);
		else
			data = this.contractSrv.getContractStatusTotal(start, end, ContractType.MAIN_CONTRACT_TYPES);

		Map<String, Object> ret = new HashMap<String, Object>();

		ret.put("xData", data.keySet());
		ret.put("yData", data.values());

		return ret;
	}

	@RequestMapping(value = "/ht-money-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getHtMoneyTotal(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		DetachedCriteria dc = this.contractSrv.getDc(null);

		// 只统计收款合同（两个收款主合同）
		dc.add(Restrictions.in("type", new ContractType[] {ContractType.MAIN, ContractType.B_CONTRACT}));

		if (start != null && end != null) {
			Criterion startC = Restrictions.and(Restrictions.ge("start", start), Restrictions.le("start", end));
			Criterion endC = Restrictions.and(Restrictions.ge("end", start), Restrictions.le("end", end));

			dc.add(Restrictions.or(startC, endC));
		}

		List<String> xData = new ArrayList<String>();
		xData.add("合同金额");
		xData.add("结算金额");
		xData.add("已收金额");
		xData.add("未收金额");

		int page = 1;
		List<Double> yData = new ArrayList<Double>(4);
		yData.add(0d);
		yData.add(0d);
		yData.add(0d);
		yData.add(0d);

		while (true) {
			List<Contract> data = this.contract2UserSrv.getContractOf(dc, null, null, page++, 30, FlowStatus.FS2001_CONTRACT_CREATED, FlowStatus.FS2002_CONTRACT_STARTED, FlowStatus.FS2003_CONTRACT_COMPLETED);

			if (data == null || data.isEmpty())
				break;

			for (Contract c : data) {
				// 合同金额
				yData.set(0, (yData.get(0) + (c.getPrice() == null ? 0 : c.getPrice())));
				// 结算金额
				yData.set(1, (yData.get(1) + (c.getClearingPrice() == null ? 0 : c.getClearingPrice())));
				// 已收金额
				yData.set(2, (yData.get(2) + (c.getSkje() == null ? 0 : c.getSkje())));
				// 未收金额
				yData.set(3, (yData.get(3) + (c.getWsje() == null ? 0 : c.getWsje())));
			}
		}

		Map<String, Object> ret = new HashMap<String, Object>();
		ret.put("xData", xData);
		ret.put("yData", yData);

		return ret;
	}

	/**
	 * 经营资金情况
	 * 
	 * @return
	 */
	@RequestMapping(value = "/jy-money-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getJyMoneyTotal(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		DetachedCriteria dc = this.contractSrv.getDc(null);

		// 只统计收款合同（两个收款主合同）
		dc.add(Restrictions.in("type", ContractType.MAIN_CONTRACT_TYPES));

		if (start != null && end != null) {
			Criterion startC = Restrictions.and(Restrictions.ge("start", start), Restrictions.le("start", end));
			Criterion endC = Restrictions.and(Restrictions.ge("end", start), Restrictions.le("end", end));

			dc.add(Restrictions.or(startC, endC));
		}

		List<String> xData = new ArrayList<String>();
		xData.add("总支金额");
		xData.add("已支金额");
		xData.add("未支金额");
		xData.add("利润金额");

		int page = 1;
		List<Double> yData = new ArrayList<Double>(4);
		yData.add(0d);
		yData.add(0d);
		yData.add(0d);
		yData.add(0d);

		while (true) {
			List<Contract> data = this.contract2UserSrv.getContractOf(dc, null, null, page++, 30, FlowStatus.FS2001_CONTRACT_CREATED, FlowStatus.FS2002_CONTRACT_STARTED, FlowStatus.FS2003_CONTRACT_COMPLETED);

			if (data == null || data.isEmpty())
				break;

			for (Contract c : data) {
				// 总支金额
				yData.set(0, (yData.get(0) + c.getZcje()));
				// 已支金额
				yData.set(1, (yData.get(1) + c.getFkje()));
				// 未支金额
				yData.set(2, (yData.get(2) + c.getWfje()));
				// 利润金额
				yData.set(3, (yData.get(3) + c.getLr()));
			}
		}

		Map<String, Object> ret = new HashMap<String, Object>();
		ret.put("xData", xData);
		ret.put("yData", yData);

		return ret;
	}

	/**
	 * 合同金额占比
	 * 
	 * @return
	 */
	@RequestMapping(value = "/zb-money-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getContractMoneyZb(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		String ql = "SELECT T.companyA, SUM(T.price) FROM Contract T WHERE T.type IN (:TYPE) AND T.flowStatus IN (:FLOW) {year} GROUP BY T.companyA ORDER BY SUM(T.price) DESC";

		List<Object> params = new ArrayList<Object>();

		Object[] types = ContractType.IN_MONEY_CONTRACT_TYPE.toArray();
		String type = "";
		for (Object o : types) {
			if (!StringUtils.isBlank(type))
				type += ",";
			type += "?";
			params.add(o);
		}
		ql = ql.replace(":TYPE", type);

		Object[] flows = new FlowStatus[] {FlowStatus.FS2001_CONTRACT_CREATED, FlowStatus.FS2002_CONTRACT_STARTED, FlowStatus.FS2003_CONTRACT_COMPLETED};
		String flow = "";
		for (Object o : flows) {
			if (!StringUtils.isBlank(flow))
				flow += ",";
			flow += "?";
			params.add(o);
		}
		ql = ql.replace(":FLOW", flow);

		if (start != null && end != null) {
			String startS = "(T.start >= ? and T.start <= ?)";
			String endS = "(T.end >= ? and T.end <= ?)";

			ql = ql.replace("{year}", " AND (" + startS + " OR " + endS + ") ");

			params.add(start);
			params.add(end);
			params.add(start);
			params.add(end);
		} else
			ql = ql.replace("{year}", "");

		int page = 1;
		Map<String, Object> ret = new HashMap<String, Object>();
		List<String> xData = new ArrayList<String>();
		List<Double> yData = new ArrayList<Double>();
		ret.put("xData", xData);
		ret.put("yData", yData);

		// 获取top10
		while (true) {
			@SuppressWarnings("unchecked")
			List<Object[]> data = (List<Object[]>) this.contractSrv.readPageByQL(ql, page++, 30, params.toArray());

			if (data == null || data.isEmpty())
				break;

			for (int i = 0; i < data.size(); i++) {
				Object[] d = data.get(i);

				if (d == null || d.length != 2)
					continue;

				String company = (String) d[0];
				Double count = (Double) d[1];

				if (StringUtils.isBlank(company))
					continue;

				if (count == null)
					count = 0d;

				if (i == 10) // 第11个使用合计
					xData.add("其他合计");
				else if (i < 10) // 前10个直接保存合同名称
					xData.add(company);

				if (i == 11) {
					yData.set(10, yData.get(10) + count); // 从第12个开始都叠加到第11个元素上
				} else
					yData.add(count); // 前11个直接保存值
			}
		}

		return ret;
	}

	@RequestMapping(value = "/ht-company-a-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getHtCompanyATotal(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		String ql = "SELECT T.companyA, COUNT(T) FROM Contract T WHERE T.type IN (:TYPE) AND T.flowStatus IN (:FLOW) {year} GROUP BY T.companyA ORDER BY COUNT(T) DESC, T.companyA";

		List<Object> params = new ArrayList<Object>();

		Object[] types = ContractType.IN_MONEY_CONTRACT_TYPE.toArray();
		String type = "";
		for (Object o : types) {
			if (!StringUtils.isBlank(type))
				type += ",";
			type += "?";
			params.add(o);
		}
		ql = ql.replace(":TYPE", type);

		Object[] flows = new FlowStatus[] {FlowStatus.FS2001_CONTRACT_CREATED, FlowStatus.FS2002_CONTRACT_STARTED, FlowStatus.FS2003_CONTRACT_COMPLETED};
		String flow = "";
		for (Object o : flows) {
			if (!StringUtils.isBlank(flow))
				flow += ",";
			flow += "?";
			params.add(o);
		}
		ql = ql.replace(":FLOW", flow);

		if (start != null && end != null) {
			String startS = "(T.start >= ? and T.start <= ?)";
			String endS = "(T.end >= ? and T.end <= ?)";

			ql = ql.replace("{year}", " AND (" + startS + " OR " + endS + ") ");

			params.add(start);
			params.add(end);
			params.add(start);
			params.add(end);
		} else
			ql = ql.replace("{year}", "");

		int page = 1;
		Map<String, Object> ret = new HashMap<String, Object>();
		List<String> xData = new ArrayList<String>();
		List<Long> yData = new ArrayList<Long>();
		ret.put("xData", xData);
		ret.put("yData", yData);

		// 获取top10
		while (true) {
			@SuppressWarnings("unchecked")
			List<Object[]> data = (List<Object[]>) this.contractSrv.readPageByQL(ql, page++, 30, params.toArray());

			if (data == null || data.isEmpty())
				break;

			for (Object[] os : data) {
				String s = (String) os[0];
				long i = (long) os[1];

				if (StringUtils.isBlank(s))
					continue;

				if (i == 10) // 第11个使用合计
					xData.add("其他合计");
				else if (i < 10) // 前10个直接保存合同名称
					xData.add(s);

				if (i == 11) {
					yData.set(10, yData.get(10) + i); // 从第12个开始都叠加到第11个元素上
				} else
					yData.add(i); // 前11个直接保存值
			}
		}

		return ret;
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/cost-total", method = RequestMethod.POST)
	@ResponseBody
	public Object getCostTotal(@DateTimeFormat(pattern = "yyyy-M-d") Date start, @DateTimeFormat(pattern = "yyyy-M-d") Date end) {
		List<String> keys = this.constants.getBidPayoutNames(null);

		if (keys == null)
			keys = new ArrayList<String>();

		keys.add("购买标书");
		keys.add("中标服务费");

		Map<String, Double> data = new LinkedHashMap<String, Double>();

		for (String key : keys) {
			data.put(key, 0d);
		}

		List<Object> param = new ArrayList<Object>();

		String where = "WHERE T.name in (";
		for (int i = 0; i < keys.size(); i++) {
			where += "?,";
			param.add(keys.get(i));
		}
		where = where.substring(0, where.length() - 1) + ")";

		if (start != null) {
			where += " AND T.time >= ?";
			param.add(start);
		}

		if (end != null) {
			where += " AND T.time <= ?";
			param.add(end);
		}

		List<Object[]> cost = new ArrayList<Object[]>();

		// 招标费用指出
		String ql = "SELECT T.name, SUM(T.total) FROM BidMoney T " + where + " GROUP BY T.name";
		List<Object[]> tmp = (List<Object[]>) this.bidSrv.readByQL(ql, param.toArray());
		if (tmp != null)
			cost.addAll(tmp);

		// 合同费用指出
		ql = "SELECT T.name, SUM(T.total) FROM ContractMoney T " + where + " GROUP BY T.name";
		tmp = (List<Object[]>) this.bidSrv.readByQL(ql, param.toArray());
		if (tmp != null)
			cost.addAll(tmp);

		for (Object[] c : cost) {
			if (c == null || c.length != 2)
				continue;
			String key = (String) c[0];
			Double val = (Double) c[1];

			if (!data.containsKey(key))
				continue;

			if (val == null)
				val = 0d;

			data.put(key, data.get(key) + val);
		}

		Map<String, Object> ret = new HashMap<String, Object>();

		ret.put("xData", data.keySet());
		ret.put("yData", data.values());

		return ret;
	}

	/**
	 * 新建合同时可以关联投标信息(未签订合同)
	 * 
	 * @return
	 */
	@RequestMapping("/get-bid-for-link-contract-not-sign")
	public String getBidForLinkedContractNotSign(Integer page, Integer pageSize, Model model) {
		String view = "app/front-page/get-bid-for-link-contract-not-sign";

		ProjectionList l = Projections.projectionList();
		l.add(Property.forName("id").as("id"));
		l.add(Property.forName("ownCompany").as("ownCompany"));
		l.add(Property.forName("projectNo").as("projectNo"));
		l.add(Property.forName("name").as("name"));

		DetachedCriteria dc = this.bidSrv.getDc(null, "bid");
		dc.setProjection(l);
		dc.add(Restrictions.eq("status", BidStatus.B0003_WIN));

		dc.setResultTransformer(Transformers.aliasToBean(Bid.class));

		OrderEntity oe = new OrderEntity();
		oe.add(MySQlConvertOrder.asc("ownCompany"));
		oe.asc("projectNo");

		String[] userIds = new String[] {this.getUser().getId()};

		if (page == null || page < 0)
			page = 1;

		if (pageSize == null || pageSize < 0)
			pageSize = 15;

		List<Bid> data = this.bid2UserSrv.getBidOf(dc, userIds, true, oe, page, pageSize, FlowStatus.FS1001_BID_CONTRACT_CREATED);

		model.addAttribute("data", data);
		model.addAttribute("page", page);
		model.addAttribute("pageSize", pageSize);
		model.addAttribute("count", this.bid2UserSrv.getBidCountOf(dc, userIds, true, FlowStatus.FS1001_BID_CONTRACT_CREATED));

		return view;
	}

	/**
	 * 新建合同时可以关联投标信息(已签订合同)
	 * 
	 * @return
	 */
	@RequestMapping("/get-bid-for-link-contract-signed")
	public String getBidForLinkedContractSigned(Integer page, Integer pageSize, Model model) {
		String view = "app/front-page/get-bid-for-link-contract-signed";

		ProjectionList l = Projections.projectionList();
		l.add(Property.forName("id").as("id"));
		l.add(Property.forName("ownCompany").as("ownCompany"));
		l.add(Property.forName("projectNo").as("projectNo"));
		l.add(Property.forName("name").as("name"));

		DetachedCriteria dc = this.bidSrv.getDc(null, "bid");
		dc.setProjection(l);
		dc.add(Restrictions.eq("status", BidStatus.B0003_WIN));
		dc.add(Restrictions.eq("flowStatus", FlowStatus.FS1002_BID_COMPLETED));

		dc.setResultTransformer(Transformers.aliasToBean(Bid.class));

		OrderEntity oe = new OrderEntity();
		oe.add(MySQlConvertOrder.asc("ownCompany"));
		oe.desc("openingTime");
		oe.asc("projectNo");

		String[] userIds = new String[] {this.getUser().getId()};

		if (page == null || page < 0)
			page = 1;

		if (pageSize == null || pageSize < 0)
			pageSize = 15;

		List<Bid> data = this.bid2UserSrv.getBidOf(dc, userIds, false, oe, page, pageSize, FlowStatus.FS1001_BID_CONTRACT_CREATED);

		model.addAttribute("data", data);
		model.addAttribute("page", page);
		model.addAttribute("pageSize", pageSize);
		model.addAttribute("count", this.bid2UserSrv.getBidCountOf(dc, userIds, false, FlowStatus.FS1001_BID_CONTRACT_CREATED));

		return view;
	}

	/**
	 * 获取所有未填写中标服务费的投标信息
	 * 
	 * @return
	 */
	public List<Bid> getBidWithNoServerMoneyInfo(OrderEntity order) {
		Bid search = new Bid();
		search.setServerMoneyState(false);
		search.setStatus(BidStatus.B0003_WIN);

		DetachedCriteria dc = this.bidSrv.getDc(search);

		String[] userIds = new String[] {this.getUser().getId()};

		List<Bid> data = this.bid2UserSrv.getAllBidOf(dc, userIds, null, order);

		return data == null || data.isEmpty() ? null : data;
	}

	private List<Bid> myTodoBid(OrderEntity order) {
		String[] userIds = new String[] {this.getUser().getId()};

		List<Bid> data = this.bid2UserSrv.getAllBidOf(null, userIds, true, order, FlowStatus.FS1000_BID_CREATED);

		return data == null || data.isEmpty() ? null : data;
	}

	private List<Bid> myBidForContract(DetachedCriteria dc, OrderEntity order) {
		String[] userIds = new String[] {this.getUser().getId()};

		List<Bid> data = this.bid2UserSrv.getAllBidOf(dc, userIds, true, order, FlowStatus.FS1001_BID_CONTRACT_CREATED);

		return data == null || data.isEmpty() ? null : data;
	}

	private List<ContractWorkPlan> myWorkPlan() {
		List<ContractWorkPlan> data = this.contractWorkPlanSrv.getAlarmPlanList(this.getUser().getId(), this.get7DaysAfterNow());

		return data == null || data.isEmpty() ? null : data;
	}

	private List<ContractPayinPlan> myPayinPlan() {
		List<ContractPayinPlan> data = this.contractPayinPlanSrv.getAlarmPlanList(this.getUser().getId(), this.get7DaysAfterNow());

		return data == null || data.isEmpty() ? null : data;
	}

	private List<ContractPayoutPlan> myPayoutPlan() {
		List<ContractPayoutPlan> data = this.contractPayoutPlanSrv.getAlarmPlanList(this.getUser().getId(), this.get7DaysAfterNow());

		return data == null || data.isEmpty() ? null : data;
	}

	private List<Contract> contractForStart() {
		Contract search = new Contract();
		search.setStatus(ContractStatus.WAIT);
		search.setFlowStatus(FlowStatus.FS2001_CONTRACT_CREATED);

		List<Contract> data = this.contractSrv.readByEntity(search);

		return data == null || data.isEmpty() ? null : data;
	}

	private List<BidMoney> getBackTbbzj() {
		List<BidMoney> data = this.bidMoneySrv.getNeedBackMoney(null, this.get7DaysAfterNow(), this.getUser().getId());

		return data == null || data.isEmpty() ? null : data;
	}

	private List<?> getContractBzj() {
		String ql = "SELECT T, T.contract.id, T.contract.name, T.contract.no FROM ContractMoney T LEFT JOIN T.contract C WHERE 1=1 ";
		ql += "AND C.type IN (?,?)";
		ql += "AND T.backTime IS NOT NULL ";
		ql += "AND T.backTime <= ?";
		ql += "AND T.gaveBack=? ";
		ql += "AND T.name IN (?,?,?) ";
		ql += "ORDER BY T.backTime, T.name";

		// 只处理收款合同
		Object[] params = new Object[] {ContractType.MAIN, ContractType.B_CONTRACT};

		params = ArrayUtils.add(params, this.get7DaysAfterNow());

		params = ArrayUtils.addAll(params, false, "质保金", "预付款保函", "履约保函");

		return this.contractMoneySrv.readByQL(ql, params);
	}

	private Date get7DaysAfterNow() {
		Calendar c = Calendar.getInstance();

		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);

		c.add(Calendar.DATE, this.ALARM_DATE_SIZE + 1);

		return c.getTime();
	}

}
